#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <poll.h>
#include <time.h>
#include <sys/time.h>

#include "soft_timer.h"

pthread_t thd_tick;

struct sft_tmr_t *sft_tmr1;
struct sft_tmr_t *sft_tmr2;
struct sft_tmr_t *sft_tmr3;
struct sft_tmr_t *sft_tmr4;

void sysUsecTime(void)
{
    struct timeval tv;
    struct timezone tz;

    /*经测试，在linux下达不到精确的定时，与linux系统有关*/

    gettimeofday(&tv, &tz);
    printf("tv_msec:%ld\n",tv.tv_sec * 1000 + tv.tv_usec / 1000);
}

static void* task_timer_1_ms(void *para)
{
    int ret;

    for(;;)
    {
        ret = poll(NULL, 0, 1);
        if(ret < 0)
        {
            perror("poll");
            break;
        }
        if(!ret)
        {
            sft_tmr_inc_tick();
            sft_tmr_loop();
        }
    }

    return (void *)0;
}

void sft_tmr_callback_1(void *para)
{
    printf("%p ", para);
    sysUsecTime();

    sft_tmr_pause(sft_tmr1);
}

void sft_tmr_callback_2(void *para)
{
    printf("%p ", para);
    sysUsecTime();
}

void sft_tmr_callback_3(void *para)
{
    printf("%p ", para);
    sysUsecTime();

    sft_tmr_start(sft_tmr3, 0);
}

void sft_tmr_callback_4(void *para)
{
    printf("%p ", para);
    sysUsecTime();
}

int main(int argc, char *argv[])
{
    pthread_attr_t attr;
    struct sched_param param;

    //设置为实时线程
    pthread_attr_init(&attr);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
    param.sched_priority = 1;
    pthread_attr_setschedparam(&attr, &param);

    pthread_create(&thd_tick,&attr,task_timer_1_ms,NULL);

    sft_tmr_create(&sft_tmr1, 1000, 1, sft_tmr_callback_1, (void *)1);
    sft_tmr_start(sft_tmr1, 0);
    tmr_list_for_each();
    sft_tmr_create(&sft_tmr2, 2000, 1, sft_tmr_callback_2, (void *)2);
    sft_tmr_start(sft_tmr2, 0);
    tmr_list_for_each();
    sft_tmr_pause(sft_tmr1);
    sft_tmr_change_period(sft_tmr1, 2000);
    sft_tmr_start(sft_tmr1, 0);
    sft_tmr_create(&sft_tmr3, 1000, 0, sft_tmr_callback_3, (void *)3);
    sft_tmr_start(sft_tmr3, 0);
    tmr_list_for_each();
    sft_tmr_create(&sft_tmr4, 1000, 1, sft_tmr_callback_4, (void *)4);
    sft_tmr_start(sft_tmr4, 0);
    tmr_list_for_each();
    sft_tmr_delete(sft_tmr2);
    tmr_list_for_each();

#if 1
    for(;;)
    {
        pause();
    }
#endif

printf("*********************************\r\n");

    sft_tmr_delete(sft_tmr2);
    tmr_list_for_each();
    sft_tmr_delete(sft_tmr3);
    tmr_list_for_each();
    sft_tmr_delete(sft_tmr4);
    tmr_list_for_each();
    sft_tmr_delete(sft_tmr1);
    tmr_list_for_each();

    return 0;
}
